package ch.netcetera.planningpoker.client.ui.participant.create;

import java.util.logging.Level;
import java.util.logging.Logger;

import ch.netcetera.planningpoker.client.model.GameProxy;
import ch.netcetera.planningpoker.client.model.ParticipantProxy;
import ch.netcetera.planningpoker.client.ui.main.MainPagePresenter;
import ch.netcetera.planningpoker.client.ui.participant.play.PlayPresenter;
import ch.netcetera.planningpoker.shared.GameRequestFactory;
import ch.netcetera.planningpoker.shared.ParticipantRequest;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.event.dom.client.HasKeyUpHandlers;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.event.dom.client.KeyUpHandler;
import com.google.gwt.user.client.ui.HasText;
import com.google.inject.Inject;
import com.google.web.bindery.event.shared.EventBus;
import com.google.web.bindery.requestfactory.shared.Receiver;
import com.gwtplatform.mvp.client.Presenter;
import com.gwtplatform.mvp.client.View;
import com.gwtplatform.mvp.client.annotations.NameToken;
import com.gwtplatform.mvp.client.annotations.ProxyCodeSplit;
import com.gwtplatform.mvp.client.proxy.PlaceManager;
import com.gwtplatform.mvp.client.proxy.PlaceRequest;
import com.gwtplatform.mvp.client.proxy.ProxyPlace;
import com.gwtplatform.mvp.client.proxy.RevealContentEvent;

public class CreateParticipantPresenter
        extends
        Presenter<CreateParticipantPresenter.IView, CreateParticipantPresenter.IProxy> {

    private static final Logger logger = Logger
            .getLogger(CreateParticipantPresenter.class.getName());

    public static final String NAME_TOKEN = "participant";
    public static final String ARG_GAME_ID = "gameId";
    public static final String ARG_GAME_NAME = "gameName";

    @ProxyCodeSplit
    @NameToken("participant")
    public interface IProxy extends ProxyPlace<CreateParticipantPresenter> {

    }

    public interface IView extends View {

        HasClickHandlers getLogin();
        
        HasKeyUpHandlers getUserNameForEnter();

        HasText getUserName();

        HasText getLabel();

        void setWaiting(boolean isWaiting);
    }

    private GameRequestFactory requestFactory;
    private PlaceManager placeManager;
    private Long gameId;

    @Inject
    public CreateParticipantPresenter(EventBus eventBus,
            PlaceManager placeManager, IView view, IProxy proxy,
            GameRequestFactory requestFactory) {
        super(true, eventBus, view, proxy);
        this.requestFactory = requestFactory;
        this.placeManager = placeManager;
    }

    @Override
    public void prepareFromRequest(PlaceRequest request) {
        super.prepareFromRequest(request);

        String gameIdString = request.getParameter(ARG_GAME_ID, "");

        logger.info("Landed on moderation argument gameId : " + gameIdString);

        try {
            gameId = Long.valueOf(gameIdString);
        } catch (NumberFormatException e) {
            logger.log(Level.SEVERE, "parsing parameter failed", e);
        }

        // TODO add error to gui

        if (gameId != null) {
            requestFactory.getGameRequest().findGame(gameId)
                    .fire(new Receiver<GameProxy>() {

                        @Override
                        public void onSuccess(GameProxy game) {
                            getView().getLabel().setText(
                                    "Choose your username to join the game <"
                                            + game.getTitle() + ">:");
                        }
                    });
        }

    }

    @Override
    protected void onBind() {
        getView().getLogin().addClickHandler(new ClickHandler() {

            @Override
            public void onClick(ClickEvent event) {

                createParticipant();

            }
        });
        getView().getUserNameForEnter().addKeyUpHandler(new KeyUpHandler() {
            
            @Override
            public void onKeyUp(KeyUpEvent event) {
                if(event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
                    createParticipant();
                }
            }
        });
    }
    
    private void createParticipant() {
        final String username = getView().getUserName().getText();
        
        ParticipantRequest participantRequest = requestFactory
                .getParticipantRequest();
        participantRequest.createDistinctParticipant(username, gameId)
        .fire(new Receiver<ParticipantProxy>() {
            
            @Override
            public void onSuccess(ParticipantProxy participant) {
                System.out
                .println("created unique participant <"
                        + participant.getName()
                        + "> for game <" + gameId + ">");
                
                PlaceRequest request = new PlaceRequest(
                        PlayPresenter.NAME_TOKEN).with(
                                PlayPresenter.ARG_GAME_ID,
                                String.valueOf(gameId)).with(
                                        PlayPresenter.ARG_PARTICIPANT_ID,
                                        String.valueOf(participant.getId()));
                
                placeManager.revealPlace(request, true);
            }
        });
    }

    @Override
    protected void revealInParent() {
        RevealContentEvent.fire(this, MainPagePresenter.MainContentSlot, this);
    }

}
